home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 6 / MacMania 6.toast / / Tools&Utilities / TouchMe 1.2□ / touchMe 1.2 Folder / touchMe source codes / CW11 PP source / source / CTouchMeMainWindowDD.cp < prev    next >
Encoding:
Text File  |  1997-04-25  |  13.4 KB  |  476 lines  |  [TEXT/CWIE]

  1. // ==================================================
  2. //    CTouchMeMainWindowDD.cp
  3. //    a part of CTouchMeMainWindow.cp
  4. //    Copyright (C) 1996-1997 Mizutori Tetsuya
  5. //    July 4, 1996; August 4, 1996; February 3, 1997; April 24, 1997.
  6. // ==================================================
  7. //    All documents are pretty-printed in 10-point Geneva font.
  8.  
  9. #include <LPane.h>
  10. #include <LDragTask.h>
  11. #include <UDrawingState.h>
  12. #include <UDrawingUtils.h>
  13. #include <LBroadcaster.h>
  14. #include <LCommander.h>
  15.  
  16. #include <PP_Messages.h>
  17.  
  18. #include "touchMeConstants.h"
  19. #include "CTouchMeMainWindow.h"
  20. #include "CTouchMeMainWindowDD.h"
  21. #include "CDateEditField.h"
  22. #include "CFlavor.h"
  23. #include "UFileTools.h"
  24. #include "UDragDropSuit.h"
  25.  
  26.  
  27. #ifdef COMMENT
  28. enum {
  29.     flavorTypeHFS            = 'hfs ',
  30.     flavorTypePromiseHFS    = 'phfs',
  31.     flavorTypeDirectory        = 'diry'
  32. };
  33.  
  34. typedef struct HFSFlavor {
  35.     OSType                fileType;
  36.     OSType                fileCreator;
  37.     unsigned short            fdFlags;
  38.     FSSpec                fileSpec;
  39. } HFSFlavor;
  40. #endif // COMMENT
  41.  
  42. const FlavorType        flavorTypeText    = 'TEXT';
  43.  
  44. const PaneIDT    thePaneList[] = {
  45.     kMain_CrTextEditDate,
  46.     kMain_CrTextEditTime,
  47.     kMain_MdTextEditDate,
  48.     kMain_MdTextEditTime,
  49.     kNoPaneID };
  50.  
  51.  
  52. // ==================================================
  53. //    Drag and Drop
  54. // ==================================================
  55.  
  56. // --------------------------------------------------
  57. //        • ItemIsAcceptable
  58. // --------------------------------------------------
  59. //    Accept 'TEXT' or HFS-type files, which are dragged from Finder.
  60.  
  61. Boolean
  62. CTouchMeMainWindow::ItemIsAcceptable(
  63.     DragReference    inDragRef,
  64.     ItemReference    inItemRef )
  65. {
  66.     FlavorFlags    theFlags;
  67.  
  68.     // Accept HFS-type files, which are dragged from Finder.
  69.     if ( IsEnabled() &&
  70.         (::GetFlavorFlags( inDragRef, inItemRef, flavorTypeHFS, &theFlags ) == noErr) ) {
  71.             mTextDrag = false;
  72.             return true;
  73.     }
  74.  
  75.     // Accept 'TEXT' type, which are dragged from Finder.
  76.     if ( IsEnabled() &&
  77.         (::GetFlavorFlags( inDragRef, inItemRef, flavorTypeText, &theFlags ) == noErr) ) {
  78.             mTextDrag = true;
  79.             return true;
  80.     }
  81.  
  82.     return false;
  83. }
  84.  
  85.  
  86. // --------------------------------------------------
  87. //        • ReceiveDragItem
  88. // --------------------------------------------------
  89.  
  90. void
  91. CTouchMeMainWindow::ReceiveDragItem(
  92.     DragReference    inDragRef,
  93.     DragAttributes    inDragAttrs,
  94.     ItemReference    inItemRef,
  95.     Rect &        inItemBounds )
  96. {
  97. #pragma unused ( inDragAttrs, inItemBounds )
  98. //    OSErr        err;
  99.  
  100.     if ( mTextDrag ) {
  101.         mTextDrag = false;
  102.         if ( UDragDropSuit::InDragRegion( inDragRef ) )
  103.             Throw( dragNotAcceptedErr );
  104.     }
  105.  
  106.     // Get the flavor data.
  107.     CFlavor    theFlavor( inDragRef, inItemRef );
  108.  
  109.     switch ( theFlavor.mType ) {
  110.         case flavorTypeHFS:
  111.         {
  112.         FSSpec    theFSSpec = theFlavor.mFSSpec;
  113.         if ( ! mModifier ) {
  114.     //    if ( ! IsModifierKeyPressed( inDragRef ) ) {
  115.  
  116.             // Do execute 'touch' theFSSpec, if the option-key is not pressed.
  117.             ProcessCommand( msg_Touch, (void *) &theFSSpec );
  118.  
  119.         } else {
  120.  
  121.             // If the option-key is pressed,
  122.             // Set date time EditFields by the stamp of theFSSpec, if no modifier key is pressed.
  123.             // If the file was dropped on some EditField, then the only one EditField will be changed.
  124.             // Now, get the mouse location and convert to port coordinates.
  125.             Point        thePoint;
  126.             ::GetDragMouse( inDragRef, &thePoint, NULL );
  127.             GlobalToPortPoint( thePoint );
  128.             PaneIDT    thePaneID = FindPaneByMouse( thePoint );
  129.  
  130.             switch ( thePaneID ) {
  131.                 case kMain_CrTextEditDate:
  132.                     BroadcastMessage( msg_Main_DroppedFileCrDate, (void *) &theFSSpec );
  133.                     break;
  134.                 case kMain_CrTextEditTime:
  135.                     BroadcastMessage( msg_Main_DroppedFileCrTime, (void *) &theFSSpec );
  136.                     break;
  137.                 case kMain_MdTextEditDate:
  138.                     BroadcastMessage( msg_Main_DroppedFileMdDate, (void *) &theFSSpec );
  139.                     break;
  140.                 case kMain_MdTextEditTime:
  141.                     BroadcastMessage( msg_Main_DroppedFileMdTime, (void *) &theFSSpec );
  142.                     break;
  143.                 default:
  144.                     BroadcastMessage( msg_Main_DroppedFile, (void *) &theFSSpec ); break;
  145.             }
  146.  
  147.         }
  148.         }
  149.         break;
  150.  
  151.         case flavorTypeText:
  152.         {
  153.             // Set date time EditFields by the dropped 'TEXT' string.
  154.             // If the 'TEXT' was dropped on some EditField, then the only one EditField will be changed.
  155.             // Now, get the mouse location and convert to port coordinates.
  156.             Handle    theTextH = theFlavor.mTextH;
  157.             long        theTextLen = theFlavor.mTextLen;
  158.             Str255    theString;
  159.             theString[0] = theTextLen;
  160.             ::BlockMoveData( *theTextH, &theString[1], theString[0] );
  161.  
  162.             Point        thePoint;
  163.             ::GetDragMouse( inDragRef, &thePoint, NULL );
  164.             GlobalToPortPoint( thePoint );
  165.             PaneIDT    thePaneID = FindPaneByMouse( thePoint );
  166.  
  167.             switch ( thePaneID ) {
  168.                 case kMain_CrTextEditDate:
  169.                     BroadcastMessage( msg_Main_DroppedTextCrDate, (void *) theString );
  170.                     break;
  171.                 case kMain_CrTextEditTime:
  172.                     BroadcastMessage( msg_Main_DroppedTextCrTime, (void *) theString );
  173.                     break;
  174.                 case kMain_MdTextEditDate:
  175.                     BroadcastMessage( msg_Main_DroppedTextMdDate, (void *) theString );
  176.                     break;
  177.                 case kMain_MdTextEditTime:
  178.                     BroadcastMessage( msg_Main_DroppedTextMdTime, (void *) theString );
  179.                     break;
  180.                 default:
  181.                     // Do zoom back rect bounds if the drag was failed.
  182.                 //    UDragDropSuit::ZoomBackBounds( inDragRef, inItemRef );
  183.                     // Instead of zooming rects by myself, we throw error exception
  184.                     // to LDragAndDrop::DoDragReceive, which will cancel Finder's trace drag.
  185.                     Throw( dragNotAcceptedErr );
  186.                     break;
  187.             }
  188.         }
  189.         break;
  190.  
  191.         default:
  192.             ThrowOSErr_( badDragFlavorErr );
  193.         break;
  194.     }
  195.  
  196. }
  197.  
  198.  
  199. // --------------------------------------------------
  200. //        • EnterDropArea
  201. // --------------------------------------------------
  202.  
  203. void
  204. CTouchMeMainWindow::EnterDropArea(
  205.     DragReference    inDragRef,
  206.     Boolean        inDragHasLeftSender )
  207. {
  208. #pragma unused (inDragHasLeftSender)
  209.  
  210.     // True if the dragged item is a text from my text edit field.
  211.     mTextDrag = mTextDrag || UDragDropSuit::InDragRegion( inDragRef );
  212.  
  213.     // Check the status of modifier keys, whether it is pressed or not.
  214.     mModifier = IsModifierKeyPressed( inDragRef );
  215.  
  216.     // Invalidate the last hilite pane.
  217.     mHilitePaneID = kNoPaneID;
  218.  
  219.     // Before ::ShowDragHilite() and ::HideDragHilite(), we must seup the graf port status
  220.     // by calling ApplyForeAndBackColors(). This is needed because we have changed our
  221.     // background color of the window.
  222.     FocusDropArea();
  223.     ApplyForeAndBackColors();
  224.  
  225.     // Call inherited.
  226.     LDragAndDrop::EnterDropArea( inDragRef, inDragHasLeftSender || mTextDrag );
  227.  
  228.     // Remember the last (latent) target before a drag & drop operation.
  229. //    mTargetID = kNoPaneID;    // This time, we do not use ID number.
  230.     mTarget = NULL;
  231.  
  232.     // Get the EditField as a target commander among four EditFields.
  233.     // If the dialog is in front, then 'GetTarget()' returns the target EditField.
  234.     // If it is not in front or in background, then the dialog itself is a latent sub commander,
  235.     // so that the desired EditField is to be get by 'GetLatentSub()' of the dialog.
  236.     LCommander *        theTarget = GetTarget();
  237.     LCommander *        theLatentTarget = GetLatentSub();
  238.     if ( theLatentTarget != NULL )
  239.         theTarget = theLatentTarget->GetLatentSub();
  240.  
  241.     if ( theTarget != NULL ) {
  242.         // If a target exists, it must be an EditField and then should be deactivated.
  243.         // You can confirm which the target is a type of EditField, as follows.
  244.         //    PaneIDT    iPaneID, iTargetPaneID;
  245.         //    iTargetPaneID = ((CDateEditField *) theTarget)->GetPaneID();
  246.         //    Boolean    found=false;
  247.         //    for ( short i=0; (iPaneID=thePaneList[i]) != kNoPaneID; i++ )
  248.         //        if ( iTargetPaneID == iPaneID ) { found=true; }
  249.         //    if ( found ) mTargetID = iTargetPaneID;
  250.         mTarget = theTarget;
  251.         // Let's deactivate the TE field because the hilite color can be
  252.         // distinguished between colors by selection and HiliteRect().
  253.         mTEActive = ((CDateEditField *) theTarget)->GetTEActive();
  254.         // Check if it is a dragging text or not.
  255.         if ( ! mTextDrag ) ((CDateEditField *) theTarget)->SetTEActive( false );
  256.     }
  257. }
  258.  
  259.  
  260. // --------------------------------------------------
  261. //        • LeaveDropArea
  262. // --------------------------------------------------
  263.  
  264. void
  265. CTouchMeMainWindow::LeaveDropArea(
  266.     DragReference    inDragRef )
  267. {
  268.     // Before ::ShowDragHilite() and ::HideDragHilite(), we must seup the graf port status
  269.     // by calling ApplyForeAndBackColors(). This is needed because we have changed our
  270.     // background color of the window.
  271. //    FocusDropArea();
  272. //    ApplyForeAndBackColors();
  273.  
  274.     // Check the status of modifier keys, which is pressed or not.
  275. //    mModifier = false;
  276. //    mTextDrag = false;
  277.  
  278.     // Invalidate the last hilite pane.
  279.     HilitePane( mHilitePaneID );
  280.     mHilitePaneID = kNoPaneID;
  281.  
  282.     // Restore the last (latent) target before a drag & drop operation.
  283. //    if ( mTargetID != kNoPaneID ) {    // This time, we do not use ID number.
  284.     if ( mTarget != NULL ) {
  285.     //    LCommander *    theTarget = (LCommander *) FindPaneByID( mTargetID );
  286.     //    SwitchTarget( theTarget );
  287.         ((CDateEditField *) mTarget)->SetTEActive( mTEActive );
  288.     }
  289. //    mTargetID = kNoPaneID;
  290.     mTarget = NULL;
  291.  
  292.     // Call inherited.
  293.     LDragAndDrop::LeaveDropArea( inDragRef );
  294. }
  295.  
  296.  
  297. // --------------------------------------------------
  298. //        • InsideDropArea
  299. // --------------------------------------------------
  300.  
  301. void
  302. CTouchMeMainWindow::InsideDropArea(
  303.     DragReference    inDragRef )
  304. {
  305.     // Call inherited.
  306.     LDragAndDrop::InsideDropArea( inDragRef );
  307.  
  308.     // If option-key is not pressed, then hilite area is the bound of this dialog box.
  309. //    if ( ! IsModifierKeyPressed( inDragRef ) ) return;
  310.     if ( ! mModifier && ! mTextDrag ) return;
  311.  
  312.     // Set the current port to this dialog.
  313.     if ( ! FocusDraw() )  return;
  314.  
  315.     // Get the mouse location and convert to port coordinates.
  316.     Point        thePoint;
  317.     ::GetDragMouse( inDragRef, &thePoint, NULL );
  318.     GlobalToPortPoint( thePoint );
  319.  
  320.     // If dragging position is in some EditField, then the EditField turns to be hilited.
  321.     PaneIDT    thePaneID = FindPaneByMouse( thePoint );
  322.     if ( thePaneID != mHilitePaneID ) HilitePane( thePaneID );
  323. }
  324.  
  325.  
  326. // --------------------------------------------------
  327. //        • HiliteDropArea
  328. // --------------------------------------------------
  329.  
  330. void
  331. CTouchMeMainWindow::HiliteDropArea(
  332.     DragReference    inDragRef )
  333. {
  334.     RgnHandle    theHiliteRgnH = ::NewRgn();
  335.  
  336.     // I do not know why 'mModifier' is not updated by 'EnterDropArea()'. ???
  337. //    if ( ! IsModifierKeyPressed(inDragRef) ) {
  338.     if ( ! mModifier && ! mTextDrag ) {
  339.  
  340.         // If option-key is not pressed, the hilite region is the dialog bound of rect.
  341.         Rect        theRect;
  342.         CalcLocalFrameRect( theRect );
  343.         ::RectRgn( theHiliteRgnH, &theRect );
  344.         FocusDraw();    // 'Focus()' and 'Refresh()' seems to be required here,
  345.         Refresh();        // otherwise the 'ShowDragHilite()' does not work properly.
  346.  
  347.     } else {
  348.  
  349.         // If modifier key is pressed, the hilite region is a union of EditFields.
  350.         RgnHandle    theRgnH = ::NewRgn();
  351.         PaneIDT    iPaneID;
  352.         // Get hilite region.
  353.         for ( short i=0;  (iPaneID=thePaneList[i]) != kNoPaneID; i++ ) {
  354.             Rect        theRect;
  355.             LPane    *thePane;
  356.             thePane = (LPane *) FindPaneByID( iPaneID );
  357.             thePane->FocusDraw();    // 'Focus()' and 'Refresh()' seems to be required here,
  358.             thePane->Refresh();        // otherwise the 'ShowDragHilite()' does not work properly.
  359.             thePane->CalcPortFrameRect( theRect );
  360.             ::RectRgn( theRgnH, &theRect );
  361.             ::UnionRgn( theHiliteRgnH, theRgnH, theHiliteRgnH );
  362.         }
  363.         ::DisposeRgn( theRgnH );
  364.  
  365.     }
  366.  
  367.     ::ShowDragHilite( inDragRef, theHiliteRgnH, true );
  368.  
  369.     ::DisposeRgn( theHiliteRgnH );
  370. }
  371.  
  372.  
  373. // ==================================================
  374. //    Common functions
  375. // ==================================================
  376.  
  377. // --------------------------------------------------
  378. //        • IsModifierKeyPressed
  379. // --------------------------------------------------
  380.  
  381. Boolean
  382. CTouchMeMainWindow::IsModifierKeyPressed(
  383.     DragReference    inDragRef )
  384. {
  385.     short        theModifiers, theMouseDownModifiers, theMouseUpModifiers;
  386.  
  387.     ::GetDragModifiers( inDragRef,
  388.         &theModifiers, &theMouseDownModifiers, &theMouseUpModifiers );
  389.  
  390.     return (Boolean) ( (theModifiers & (optionKey | cmdKey) ) != 0 );
  391. }
  392.  
  393.  
  394. // --------------------------------------------------
  395. //        • FindPaneByMouse
  396. // --------------------------------------------------
  397.  
  398. PaneIDT
  399. CTouchMeMainWindow::FindPaneByMouse(
  400.     const Point        inPoint )
  401. {
  402.     PaneIDT    iPaneID;
  403.  
  404.     for ( short i=0;  (iPaneID=thePaneList[i]) != kNoPaneID; i++ ) {
  405.         Rect        theRect;
  406.         LPane    *thePane;
  407.         thePane = (LPane *) FindPaneByID( iPaneID );
  408.         thePane->CalcPortFrameRect( theRect );
  409.         if ( ::PtInRect( inPoint, &theRect ) ) return iPaneID;
  410.     }
  411.  
  412.     return (PaneIDT) kNoPaneID;
  413. }
  414.  
  415.  
  416. // --------------------------------------------------
  417. //        • HilitePane
  418. // --------------------------------------------------
  419.  
  420. void
  421. CTouchMeMainWindow::HilitePane(
  422.     const PaneIDT        inPaneID )
  423. {
  424.     // Set the current port to this dialog.
  425.     if ( ! FocusDraw() ) return;
  426.  
  427.     // Restore the previous one.
  428.     if ( mHilitePaneID != kNoPaneID ) {
  429.         LPane *    thePane = (LPane *) FindPaneByID( mHilitePaneID );
  430.         Rect        theRect;
  431.         thePane->CalcPortFrameRect( theRect );
  432.         HiliteRect( theRect );
  433.     }
  434.  
  435.     if ( inPaneID == mHilitePaneID ) return;
  436.  
  437.     // Setup the present one.
  438.     if ( inPaneID != kNoPaneID ) {
  439.         LPane *    thePane = (LPane *) FindPaneByID( inPaneID );
  440.         Rect        theRect;
  441.         thePane->CalcPortFrameRect( theRect );
  442.         HiliteRect( theRect );
  443.     }
  444.  
  445.     mHilitePaneID = inPaneID;
  446. }
  447.  
  448.  
  449. // --------------------------------------------------
  450. //        • HiliteRect
  451. // --------------------------------------------------
  452. #include <LowMem.h>
  453.  
  454. void
  455. CTouchMeMainWindow::HiliteRect(
  456.     const Rect &    inRect )
  457. {
  458. #ifdef COMMENT
  459.     // From "Highlighting" section in p.4-41,
  460.     // Apple Computer's Inside Macintosh "Imaging with QuickDraw".
  461.  
  462.     UInt8    theHiliteMode;
  463.     theHiliteMode = ::LMGetHiliteMode();
  464. //    theHiliteMode &= ~( (UInt8) 0x01 << hiliteBit );
  465.     ::BitClr( &theHiliteMode, pHiliteBit );
  466.     ::LMSetHiliteMode( theHiliteMode );
  467. #else // COMMENT
  468.     UDrawingUtils::SetHiliteModeOn();
  469. #endif // COMMENT
  470.  
  471.     ::InvertRect( &inRect );
  472. }
  473.  
  474.  
  475. // end of program
  476.